package top.lunarye.handler.handler.impl;

import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import com.google.common.base.Throwables;
import com.google.common.util.concurrent.RateLimiter;
import com.sun.mail.util.MailSSLSocketFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import top.lunarye.common.domaim.TaskInfo;
import top.lunarye.common.dto.EmailContentModel;
import top.lunarye.common.enums.ChannelType;
import top.lunarye.common.enums.RateLimitStrategy;
import top.lunarye.support.dao.EmailAccountDao;
import top.lunarye.handler.flowControl.FlowControlParam;
import top.lunarye.handler.handler.BaseHandler;
import top.lunarye.support.domain.EmailAccount;

import javax.annotation.Resource;
import java.security.GeneralSecurityException;

/**
 * @author lunar
 * @since 2022-07-21
 */
@Component
@Slf4j
public class EmailHandler extends BaseHandler {

    @Resource
    private EmailAccountDao emailAccountDao;

    public EmailHandler() {
        channelCode = ChannelType.Email.getCode();

        // 请求限流,单机限流5 qps
        Double rateInitValue = 5.0;
        flowControlParam = FlowControlParam.builder().rateInitValue(rateInitValue)
                .rateLimitStrategy(RateLimitStrategy.REQUEST_RATE_LIMIT)
                .rateLimiter(RateLimiter.create(rateInitValue)).build();
    }

    @Override
    public boolean handler(TaskInfo taskInfo) {
        EmailContentModel emailContentModel = (EmailContentModel) taskInfo.getContentModel();
        MailAccount account = getAccountConfig(taskInfo.getSendAccount());
        try {
            MailUtil.send(account, taskInfo.getReceiver(), emailContentModel.getTitle(),
                    emailContentModel.getContent(), true, null);
        } catch (Exception e) {
            log.error("EmailHandler#handler fail!{},params:{}", Throwables.getStackTraceAsString(e), taskInfo);
            return false;
        }
        return true;
    }

    /**
     * 依据传入的AccountId得到
     * @param sendAccount
     * @return
     */
    private MailAccount getAccountConfig(Integer sendAccount) {
        EmailAccount emailAccount = emailAccountDao.selectById(sendAccount);
        MailAccount mailAccount = new MailAccount();
        mailAccount.setFrom(emailAccount.getFrom());
        mailAccount.setHost(emailAccount.getHost());
        mailAccount.setPort(emailAccount.getPort());
        mailAccount.setPass(emailAccount.getPass());
        mailAccount.setUser(emailAccount.getUser());
        try {
            MailSSLSocketFactory sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            mailAccount.setAuth(true).setStarttlsEnable(true).setSslEnable(true)
                    .setCustomProperty("mail.smtp.ssl.socketFactory", sf)
                    .setTimeout(25000).setConnectionTimeout(25000);
        } catch (GeneralSecurityException e) {
            log.error("EmailHandler#getAccount fail!{}", Throwables.getStackTraceAsString(e));
        }
        return mailAccount;
    }
}
